package com.ginmeta.service.login;

import cn.dev33.satoken.secure.SaSecureUtil;
import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.collection.ListUtil;
import cn.hutool.core.date.DateUtil;
import com.ginmeta.common.enums.StatusEnum;
import com.ginmeta.common.exception.CustomException;
import com.ginmeta.common.utils.StringUtils;
import com.ginmeta.common.utils.SystemUtils;
import com.ginmeta.common.utils.security.RsaUtils;
import com.ginmeta.domain.login.LoginBody;
import com.ginmeta.domain.login.LoginUser;
import com.ginmeta.domain.login.RegisterBody;
import com.ginmeta.domain.system.entity.SysUser;
import com.ginmeta.service.system.SysRoleService;
import com.ginmeta.service.system.SysUserService;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.util.Set;

/**
 * 登陆业务层
 * @author GinMeta
 */
@Slf4j
@Service
public class LoginService {

    @Resource
    private SysUserService sysUserService;

    @Resource
    private SysRoleService sysRoleService;

    /**
     * 登陆方法
     * @param loginBody 参数
     */
    public void login(LoginBody loginBody) {
        // 根据用户名查找用户
        SysUser sysUser = sysUserService.queryChain()
                .select()
                .from(SysUser.class)
                .where(SysUser::getUsername).eq(loginBody.getUsername())
                .one();

        if (StringUtils.isNull(sysUser)) {
            log.info("用户：'{}'不存在.", loginBody.getUsername());
            throw new CustomException("用户：" + loginBody.getUsername() + " 不存在");
        }

        if (!sysUser.getPassword().equals(SaSecureUtil.sha256(RsaUtils.decryptByPrivateKey(loginBody.getPassword())))) {
            log.info("用户名或密码错误");
            throw new CustomException("用户名或密码错误");
        }

        if (!StatusEnum.NORMAL.getValue().equals(sysUser.getStatus())) {
            log.info("该账号已被停用");
            throw new CustomException("该账号已被停用");
        }

        Set<String> roleKeys = sysRoleService.selectRolePermissionByUserId(sysUser.getUserId());
        if (!roleKeys.contains("*")) {
            boolean flag = false;
            for (String type : loginBody.getTypes()) {
                if (roleKeys.contains(type)) {
                    flag = true;
                    break;
                }
            }
            if (!flag) {
                throw new CustomException("账号：" + loginBody.getUsername() + " 不存在");
            }
        }

        // 登陆
        StpUtil.login(sysUser.getUserId());

        // 清除密码
        sysUser.setPassword(null);

        // 用户信息缓存
        StpUtil.getSession().set(SystemUtils.LOGIN_USER, new LoginUser(sysUser, StpUtil.getTokenInfo()));
    }

    /**
     * 注册方法
     * @param registerBody 注册参数
     */
    public void register(RegisterBody registerBody) {
        if (sysUserService.checkUsernameUnique(registerBody.getUsername())) {
            throw new CustomException("用户名'"+registerBody.getUsername()+"'已被使用");
        }
        SysUser sysUser = SysUser.builder()
                .username(registerBody.getUsername())
                .nickName(sysUserService.getRandomNickName())
                .password(SaSecureUtil.sha256(registerBody.getPassword()))
                .registrationDate(DateUtil.date())
                .roleIds(ListUtil.toList(2L))
                .build();
        // 新增用户
        boolean result = sysUserService.add(sysUser);
        if (!result) {
            throw new CustomException("注册失败，未知错误");
        }
    }
}
